import { AppDataSource } from '@weubi/shared';
import { Repository, DataSource } from 'typeorm';
import jwt, { SignOptions } from 'jsonwebtoken';



export class AuthController {
  private userRepository: Repository<any>;

  constructor(dataSource?: DataSource) {
    // 在测试环境中优先使用全局测试数据源
    let ds = dataSource;
    if (!ds && process.env.NODE_ENV === 'test') {
      const globalDataSource = (global as any).__TEST_DATA_SOURCE__;
      if (globalDataSource && globalDataSource.isInitialized) {
        ds = globalDataSource;
      }
    }
    ds = ds || AppDataSource;
    // 使用字符串名称获取仓库，避免实体实例不匹配问题
    this.userRepository = ds.getRepository('User');
  }

  // 用户注册
  async register(data: { email: string; name: string; password: string }) {
    // 检查用户是否已存在
    const existingUser = await this.userRepository.findOne({
      where: { email: data.email },
    });

    if (existingUser) {
      throw new Error('User with this email already exists');
    }

    // 创建新用户
    const user = this.userRepository.create({
      email: data.email,
      name: data.name,
      password: data.password, // 密码会在实体的 @BeforeInsert 钩子中自动哈希
    });

    const savedUser = await this.userRepository.save(user);

    // 生成令牌
    const tokens = this.generateTokens(savedUser);

    return {
      user: savedUser.toSafeJSON(),
      tokens,
    };
  }

  // 用户登录
  async login(data: { email: string; password: string }, ip?: string) {
    // 查找用户
    const user = await this.userRepository.findOne({
      where: { email: data.email },
    });

    if (!user) {
      throw new Error('Invalid credentials');
    }

    // 验证密码
    const isValidPassword = await user.validatePassword(data.password);
    if (!isValidPassword) {
      throw new Error('Invalid credentials');
    }

    // 检查用户是否激活
    if (!user.isActive) {
      throw new Error('Account is deactivated');
    }

    // 更新登录信息
    user.updateLastLogin(ip);
    await this.userRepository.save(user);

    // 生成令牌
    const tokens = this.generateTokens(user);

    return {
      user: user.toSafeJSON(),
      tokens,
    };
  }

  // 刷新令牌
  async refreshToken(refreshToken: string) {
    try {
      const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET || 'refresh-secret') as any;
      
      const user = await this.userRepository.findOne({
        where: { id: decoded.userId },
      });

      if (!user || !user.isActive) {
        throw new Error('Invalid refresh token');
      }

      // 生成新的令牌
      const tokens = this.generateTokens(user);

      return {
        user: user.toSafeJSON(),
        tokens,
      };
    } catch (error) {
      throw new Error('Invalid refresh token');
    }
  }

  // 用户登出
  async logout(userId: string) {
    // 这里可以实现令牌黑名单或其他登出逻辑
    // 暂时简单处理
    console.log(`User ${userId} logged out`);
  }

  // 获取用户资料
  async getProfile(userId: string): Promise<any | null> {
    const user = await this.userRepository.findOne({
      where: { id: userId },
    });

    return user ? user.toSafeJSON() as any : null;
  }

  // 更新用户资料
  async updateProfile(userId: string, data: any): Promise<any | null> {
    const user = await this.userRepository.findOne({
      where: { id: userId },
    });

    if (!user) {
      throw new Error('User not found');
    }

    // 更新用户信息
    if (data.name) user.name = data.name;
    if (data.avatar) user.avatar = data.avatar;
    if (data.preferences) {
      user.updatePreferences(data.preferences);
    }

    const updatedUser = await this.userRepository.save(user);
    return updatedUser.toSafeJSON() as any;
  }

  // 修改密码
  async changePassword(userId: string, data: { currentPassword: string; newPassword: string }) {
    const user = await this.userRepository.findOne({
      where: { id: userId },
    });

    if (!user) {
      throw new Error('User not found');
    }

    // 验证当前密码
    const isValidPassword = await user.validatePassword(data.currentPassword);
    if (!isValidPassword) {
      throw new Error('Current password is incorrect');
    }

    // 更新密码
    user.password = data.newPassword; // 会在 @BeforeUpdate 钩子中自动哈希
    await this.userRepository.save(user);
  }

  // 验证令牌
  async verifyToken(token: string): Promise<any | null> {
    try {
      const decoded = jwt.verify(token, process.env.JWT_SECRET || 'secret') as any;
      
      const user = await this.userRepository.findOne({
        where: { id: decoded.userId },
      });

      if (!user || !user.isActive) {
        return null;
      }

      return user;
    } catch (error) {
      return null;
    }
  }

  // 生成令牌
  private generateTokens(user: any) {
    const payload = {
      userId: user.id,
      email: user.email,
      role: user.role,
    };

    const jwtSecret = process.env.JWT_SECRET || 'secret';
    const jwtRefreshSecret = process.env.JWT_REFRESH_SECRET || 'refresh-secret';

    const accessTokenOptions: SignOptions = { expiresIn: (process.env.JWT_EXPIRES_IN || '1h') as any };
    const refreshTokenOptions: SignOptions = { expiresIn: (process.env.JWT_REFRESH_EXPIRES_IN || '7d') as any };

    const accessToken = jwt.sign(
      payload,
      jwtSecret,
      accessTokenOptions
    );

    const refreshToken = jwt.sign(
      { userId: user.id },
      jwtRefreshSecret,
      refreshTokenOptions
    );

    return {
      accessToken,
      refreshToken,
      expiresIn: 3600, // 1 hour in seconds
    };
  }
}
